package la.bbs558.util;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import la.bbs558.exception.MsgException;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
import java.util.function.Supplier;

/**
 * @Classname Objects
 * @Description 操作一下对象的工具类
 * @Date 2023/8/16 11:12
 * @Created by weihanmin
 */
public class Objs extends ObjectUtil {

    /**
     * 校验是否为有效(有值，有元素，不为空)对象
     *
     * @param object 对象
     * @return boolean
     */
    public static boolean isValid(Object object) {
        if (isNull(object)) {
            return false;
        }
        if (object instanceof Collection) {
            return CollectionUtil.isNotEmpty((Collection<?>) object);
        }
        if (object instanceof CharSequence) {
            return StrUtil.isNotBlank((CharSequence) object);
        }
        if (object instanceof Map){
            return MapUtil.isNotEmpty((Map<?, ?>) object);
        }
        if (ArrayUtil.isArray(object)) {
            return  0 != Array.getLength(object);
        }
        return true;
    }

    /**
     * 校验是否不为有效(有值，有元素，不为空)对象
     *
     * @param object 对象
     * @return boolean
     */
    public static boolean isInvalid(Object object) {
        return !isValid(object);
    }


    /**
     * 校验是否全部是合法参数
     *
     * @param objects 对象
     * @return boolean
     */
    public static boolean isAllValid(Object... objects) {
        if (objects == null) {
            return false;
        }
        for (Object object : objects) {
            boolean validate = isValid(object);
            if (!validate) {
                return false;
            }
        }
        return true;
    }
    /**
     * 校验是否全部不是合法参数
     *
     * @param objects 对象
     * @return boolean
     */
    public static boolean isAllInvalid(Object... objects) {
        if (objects == null) {
            return true;
        }
        for (Object object : objects) {
            boolean validate = isValid(object);
            if (validate) {
                return false;
            }
        }
        return true;
    }

    /**
     * 校验是否存在任一参数是和合法参数
     *
     * @param objects 对象
     * @return boolean
     */
    public static boolean isAnyValid(Object... objects) {
        if (objects == null) {
            return false;
        }
        for (Object object : objects) {
            boolean validate = isValid(object);
            if (validate) {
                return true;
            }
        }
        return false;
    }

    /**
     * 校验是否存在任一参数是非法参数
     *
     * @param objects 对象
     * @return boolean
     */
    public static boolean isAnyInvalid(Object... objects) {
        if (objects == null) {
            return true;
        }
        for (Object object : objects) {
            boolean validate = isValid(object);
            if (!validate) {
                return true;
            }
        }
        return false;
    }

    /**
     * 得到枚举
     *
     * @param tClass     t类
     * @param fieldName  字段名
     * @param fieldValue 字段值
     * @return {@link T}
     */
    public static <T> T getEnum(Class<T> tClass, String fieldName, Object fieldValue) {
        final T[] enumConstants = tClass.getEnumConstants();
        if (enumConstants == null) {
            return null;
        }
        Map<String, Field> fieldMap = ReflectUtil.getFieldMap(tClass);
        for (T enumConstant : enumConstants) {
            Field field = fieldMap.get(fieldName);
            Object value = ReflectUtil.getFieldValue(enumConstant, field);
            if (equal(value, fieldValue)) {
                return enumConstant;
            }
        }
        return null;
    }

    /**
     * 得到枚举
     *
     * @param tClass     t类
     * @param filed      提起
     * @param fieldValue 字段值
     * @return {@link T}
     */
    public static <T> T getEnum(Class<T> tClass, FieldUtil.SFunction<T, ?> filed, Object fieldValue) {
        String fieldName = FieldUtil.getFieldName(filed);
        return getEnum(tClass, fieldName, fieldValue);
    }

    /**
     * 有效,否则扔
     *
     * @param object 对象
     * @param msg    味精
     *///断言是否是可用的，否则抛出异常
    public static void valid(Object object, String msg) {
        validOrElseThrow(object,msg);
    }

    /**
     * 得到obj
     *
     * @param t   t
     * @param msg 味精
     * @return {@link T}
     */
    public static <T> T get(T t, String msg) {
        return Optional.ofNullable(t).orElseThrow(() -> new MsgException(msg));
    }

    /**
     * 得到obj
     *
     * @param t          t
     * @param defaultObj 默认obj
     * @return {@link T}
     */
    public static <T> T getOrElse(T t, T defaultObj) {
        return Optional.ofNullable(t).orElse(defaultObj);
    }


    public static <T> T validOrElse(T t, T defaultObj) {
        return isValid(t) ? t : defaultObj;
    }


    /**
     * 有效,否则抛出异常
     *
     * @param o   o
     * @param msg 味精
     */
    public static void validOrElseThrow(Object o, String msg) {
        if(isInvalid(o)){
            throw new MsgException(msg);
        }
    }

    public static void isTrue(boolean flag,String msg) {
        if(!flag){
            throw new MsgException(msg);
        }
    }

    public static void isTrue(boolean flag, Supplier<String> supplier) {
        if(!flag){
            throw new MsgException(supplier.get());
        }
    }
}
